package com.songlanyun.modules.marketing.seckill.entity;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.type.TypeReference;
import com.songlanyun.common.drive.RootEntity;
import com.songlanyun.common.enums.MarketingConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.SpringContextUtils;
import com.songlanyun.common.utils.custom.ClassConvertUtils;
import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.modules.exception.MarketingException;
import com.songlanyun.modules.goods.model.values.GoodsSkuTableItem;
import com.songlanyun.modules.goods.model.vo.ActivitySkuComItemVo;
import com.songlanyun.modules.goods.model.vo.SkuComItemVo;
import com.songlanyun.modules.goods.service.GoodsSkuService;
import com.songlanyun.modules.marketing.seckill.service.SeckillActivityGoodsService;
import com.songlanyun.modules.marketing.seckill.service.SeckillGoodsSkuService;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.math.BigDecimal;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.*;

/**
 * 秒杀活动商品表
 *
 * @author Mark
 * @email sunlightcs@gmail.com
 * @date 2020-11-23 17:30:11
 */
@Data
@TableName("yxt_marketing_seckill_activity_goods")
public class SeckillActivityGoods extends RootEntity<Long, SeckillActivityGoods> implements Serializable {
    private static final long serialVersionUID = 1L;

    {
        discount = BigDecimal.ZERO;
        fixPrice = BigDecimal.ZERO;
        limitBuyNum = 0;
        minPrice = BigDecimal.ZERO;
        maxPrice = BigDecimal.ZERO;
        realStockTotal = 0;
        initSaleNum = 0;
        realSaleNum = 0;
        resultSaleNum = 0;
        residueStockTotal = 0;
        recommended = false;
        consumptionValue = BigDecimal.ZERO;
    }

    /**
     *
     */
    @TableId
    private Long id;
    /**
     * 发布商家
     */
    private Long shopId;
    /**
     * 商品id
     */
    private Long goodsId;
    /**
     * 秒杀活动id
     */
    private Long seckillId;
    /**
     * 0固定折扣,1固定减价
     */
    private MarketingConstant.PriceType priceType;
    /**
     * 固定折扣、
     */
    private BigDecimal discount;

    public BigDecimal loadDiscount() {
        if (this.priceType.equals(MarketingConstant.PriceType.PRICE_FIXED_BY)) {
            this.discount = MathUtils.multiplyMulti(1,MathUtils.divideMulti(2,this.getMinPrice(), this.getMinSalePrice()),
                    new BigDecimal(10));
        }

        return this.discount;
    }

    /**
     * 固定减多少钱
     */
    private BigDecimal fixPrice;
    /**
     * 每人限购多少件，相同买家从此活动可购买总件数，填0代表不限制
     */
    private Integer limitBuyNum;
    /**
     * 商品排序，不填写，默认按后添加的在前
     */
    private Integer sort;
    /**
     *
     */
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    /**
     *
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
    /**
     *
     */
    private BigDecimal minPrice;
    /**
     *
     */
    private BigDecimal maxPrice;
    /**
     * 投放的真实库存总数
     */
    private Integer realStockTotal;
    /**
     * 初始化销量（假销量）
     */
    private Integer initSaleNum;
    /**
     * 真实销量
     */
    private Integer realSaleNum;
    /**
     * 输出销量(初始化销量+真实销量)
     */
    private Integer resultSaleNum;

    /**
     * 剩余库存(real_stock_total-result_sale_num)
     */
    private Integer residueStockTotal;
    /**
     * 最小销售价
     */
    private BigDecimal minSalePrice;
    /**
     * 最大销售价
     */
    private BigDecimal maxSalePrice;
    /**
     * 是推荐商品
     */
    private Boolean recommended;

    /**
     * 最低售价
     */
    private BigDecimal consumptionValue;


    /**
     * 增加销量
     *
     * @param num
     */
    public void incSaleNum(int num) {
        this.realSaleNum += num;
        if (this.realSaleNum > this.realStockTotal) {
            throw new RRException(MarketingException.SECKILL_ACTIVITY_GOODS_UNDERSTOCK);
        }
        this.computeResultSaleAndResidueStock();
    }

    /**
     * 减少销量
     *
     * @param num
     */
    public void decSaleNum(int num) {
        this.realSaleNum -= num;
        if (this.realSaleNum <= 0) {
            this.realSaleNum = 0;
        }
        this.computeResultSaleAndResidueStock();
    }

    /**
     * 在实体添加，修改之前调用，在销量增减时也会调用一次
     */
    public void computeResultSaleAndResidueStock() {
        //输出销量 = 初始化销量+真实销量
        this.resultSaleNum = this.initSaleNum + this.realSaleNum;
        //剩余库存 = 真实库存-输出销量
        this.residueStockTotal = this.realStockTotal - this.resultSaleNum;
    }


    @TableField(exist = false)
    private List<SeckillGoodsSku> seckillGoodsSkuList;

    @Override
    public Long getIdentity() {
        return id;
    }

    //==========考贝商品数据，为了不受商品sku组合的变化而影响
    //商品规格表相关=====================================================================
    /**
     * 商品的规格表
     * [
     * {"head":{"id":123,"name":"颜色"},"values":[{"id":12344,"name":"白色"},{"id":123,"name":"红色"}]}
     * {"head":{"id":12443,"name":"尺码"},"values":[{"id":1234444,"name":"175"},{"id":12443,"name":"180"}]}
     * {"head":{"id":124435,"name":"性别"},"values":[{"id":24324,"name":"男"},{"id":324323,"name":"女"}]}
     * ]
     */
    @TableField(exist = false)
    private List<GoodsSkuTableItem> skuTable;

    public void setSkuTable(List<GoodsSkuTableItem> skuTable) {
        this.skuTable = skuTable;
        this.skuTableValue = JSONUtil.toJsonStr(this.skuTable);
    }

    @JsonIgnore
    private String skuTableValue;

    /**
     * 对于从数据库映射的数据，除了设置相应的值，还需要映射成对象(手动调用)
     */
    public void setSkuTableValue(String skuTableValue) {
        this.skuTableValue = skuTableValue;
        if (StringUtils.isEmpty(this.skuTableValue)) {
            this.skuTable = new ArrayList<>();
        } else {
            try {
                this.skuTable = ClassConvertUtils.stringToClassSnake(skuTableValue, new TypeReference<List<GoodsSkuTableItem>>() {
                });
            } catch (IOException e) {
                throw new RRException("商品规格表无法转Map");
            }
        }
    }
    //商品规格表相关结束=====================================================================

    /**
     * 总库存
     */
    @TableField(exist = false)
    private Integer residualInventory;

    /**
     * 计算库存
     *
     * @return
     */
    public List<ActivitySkuComItemVo> loadResidualInventory() {

        SeckillGoodsSkuService goodsSkuService = (SeckillGoodsSkuService) SpringContextUtils.getBean("seckillGoodsSkuService");
        List<ActivitySkuComItemVo> list = goodsSkuService.loadSkuItemList(getId());
        Map<Long, Integer> temp = new HashMap<>();
        Integer total = 0;
        list.forEach(o -> {
            if (!temp.containsKey(o.getSingleGoodsId())) {
                temp.put(o.getSingleGoodsId(), o.getAbleStock());
            }
        });
        total = temp.values().stream().mapToInt(integer -> integer).sum();
        this.residualInventory = total;
        return list;
    }
}
